//! Basic DOM data structures.

use std::collections::{HashMap, HashSet};

pub type AttrMap = HashMap<String, String>;

#[derive(Debug, PartialEq)]
pub struct Node {
  // data common to all nodes:
  pub children: Vec<Node>,

  // data specific to each node type:
  pub node_type: NodeType,
}

#[derive(Debug, PartialEq)]
pub enum NodeType {
  Element(ElementData),
  Text(String),
}

#[derive(Debug, PartialEq)]
pub struct ElementData {
  pub tag_name: String,
  pub attributes: AttrMap,
}

// Constructor functions for convenience:

pub fn text(data: String) -> Node {
  Node {
    children: vec![],
    node_type: NodeType::Text(data),
  }
}

pub fn elem(name: String, attrs: AttrMap, children: Vec<Node>) -> Node {
  Node {
    children: children,
    node_type: NodeType::Element(ElementData {
      tag_name: name,
      attributes: attrs,
    }),
  }
}

// Element methods

impl ElementData {
  pub fn id(&self) -> Option<&String> {
    self.attributes.get("id")
  }

  pub fn classes(&self) -> HashSet<&str> {
    match self.attributes.get("class") {
      Some(classlist) => classlist.split(' ').collect(),
      None => HashSet::new(),
    }
  }
}
